Introdução

Neste projeto vou apresentar o trabalho final do curso de “Web scraping” da Curso-R. A ideia aqui é ter um primeiro contato com rapagem de dados de sites e também, ter uma entrega paralela como trabalho de conclusão do VIII Curso de Cannabis Medicinal da Unifesp.

Principais etapas

Veremos os seguintes pontos nesse documento:

  • Descrição da página web acessada
  • Como a requisição foi imitada?
  • Como foi realizada a iteração?
  • Como é o arquivo parseado?
  • Documentação final

Descrição da página web acessada

Alguns países possuem sites de vendas de sementes para cultivadores que desejam plantar maconha em suas próprias casas.

Um desses sites é a plataforma Seed Bank que foi projetada para disponibilizar sementes premium para cultivadores com uma excelente variedade e excelentes preços.




Já dentro do site, o interesse está nas sementes feminizadas que são sementes de cannabis que possuem genética para produzir apenas ervas fêmeas.




Os canabinoides são compostos naturais da planta. Os canabinoides mais famosos e conhecidos, são o delta-9-tetraidrocanabinol (THC) e o canabidiol (CBD). O THC é o componente psicoativo da Cannabis e o principal responsável pelos efeitos físicos e psíquicos, a famosa brisa. Já o CBD tem o seu efeito principalmente ao interagir com receptores específicos nas células do cérebro e do corpo e é muito utilizado de forma medicinal por conta dos seus efeitos anticonvulsionantes, anti-inflamatórios e antitumorais.

Para saber um pouco mais sobre o assunto, recomendo uma breve visita a página da wikipedia sobre Canabidiol.

Voltando a página de interesse, foram coletadas as informações sobre os principais canabinoides de cada variedade de semente.




Foram raspados os dados dos “Cannabinoid Totals” de cada uma das sementes feminizadas presentes no site.

Com essa pequena introdução e descrição da página, vamos começar a coleta de dados e análise de cluster das sementes.

Em primeiro lugar, foram carregados os pacotes que serão ferramentas para realização da raspagem de dados e também da clusterização.

pacotes <- c(
  "tidyverse",
  "cluster",
  "dendextend",
  "factoextra",
  "fpc",
  "gridExtra",
  "magrittr",
  "knitr",
  "kableExtra",
  "purrr",
  "xml2",
  "progressr",
  "purrr"
)


if (sum(as.numeric(!pacotes %in% installed.packages())) != 0) {
  instalador <- pacotes[!pacotes %in% installed.packages()]
  for (i in 1:length(instalador)) {
    install.packages(instalador, dependencies = T)
    break()
  }
  sapply(pacotes, require, character = T)
} else{
  sapply(pacotes, require, character = T)
}
##  tidyverse    cluster dendextend factoextra        fpc  gridExtra   magrittr 
##       TRUE       TRUE       TRUE       TRUE       TRUE       TRUE       TRUE 
##      knitr kableExtra      purrr       xml2  progressr      purrr 
##       TRUE       TRUE       TRUE       TRUE       TRUE       TRUE



Como a requisição foi imitada?

O primeiro passo, foi localizar a URL principal que contém todas as sementes daquela página específica e realizar uma requisição para obter os links daquela página.

O que eu chamo de URL mãe, é essa url principal que foi a primeira a ser acessada.




A requisição da url mãe foi realizada e o arquivo html foi salvo localmente através do código abaixo.

u_links <- "https://www.seedbank.com/collections/feminized-seeds/"

r_links <-
  httr::GET(u_links,
            httr::write_disk("output/strains/feminized.html", overwrite = TRUE))
r_links
## Response [https://www.seedbank.com/collections/feminized-seeds/]
##   Date: 2022-10-24 14:39
##   Status: 200
##   Content-Type: text/html; charset=UTF-8
##   Size: 185 kB
## <ON DISK>  C:\Users\Gauge\Desktop\projeto final\cannabis\output\strains\feminized.html

Depois de realizar essa requisição GET no site, obtivemos o status 200 e um arquivo de quase 200kB. Com a página em mãos, foi necessário imitar a requisição que acessa o link de uma semente e para isso, os elementos da página foram inspecionados.




Atráves da inspeção, foi possível localizar um elemento html que poderia ser acessado para retornar o link de todas sementes daquela página específica. Para acessar, utilizou-se o código abaixo utilizando o xpath do elemento e em seguida extraindo as urls (href) que obedecem ao filtro realizado com xpath.

links <- r_links |>
  xml2::read_html() |>
  xml2::xml_find_all("//div[@class = 'add-to-cart-button']/a")

urls <- xml2::xml_attr(links, "href")

urls
##  [1] "https://www.seedbank.com/products/chocolope-seeds/"             
##  [2] "https://www.seedbank.com/products/gorilla-glue-4-seeds/"        
##  [3] "https://www.seedbank.com/products/feminized-blue-dream-seeds/"  
##  [4] "https://www.seedbank.com/products/bruce-banner-seeds/"          
##  [5] "https://www.seedbank.com/products/gsc-seeds-girl-scout-cookies/"
##  [6] "https://www.seedbank.com/products/wedding-cake-seeds/"          
##  [7] "https://www.seedbank.com/products/northern-lights-5-seeds/"     
##  [8] "https://www.seedbank.com/products/granddaddy-purple-seeds/"     
##  [9] "https://www.seedbank.com/products/auto-purple-kush-seeds/"      
## [10] "https://www.seedbank.com/products/critical-mass-seeds/"         
## [11] "https://www.seedbank.com/products/do-si-dos-seeds/"             
## [12] "https://www.seedbank.com/products/auto-super-lemon-haze-seeds/"

Além das urls, também foi interessante obter o nome de cada uma das sementes, para construção do futuro dataset. para obtenção dos nomes, o código abaixo foi executado, obtendo o nome da própria url da semente.

txt <-
  xml2::url_relative(urls, "https://www.seedbank.com/products/") |>
  #remover traços e barras com regex
  stringr::str_replace_all("[[-/]]", " ") |>
  trimws()#remover espaço no final
txt
##  [1] "chocolope seeds"              "gorilla glue 4 seeds"        
##  [3] "feminized blue dream seeds"   "bruce banner seeds"          
##  [5] "gsc seeds girl scout cookies" "wedding cake seeds"          
##  [7] "northern lights 5 seeds"      "granddaddy purple seeds"     
##  [9] "auto purple kush seeds"       "critical mass seeds"         
## [11] "do si dos seeds"              "auto super lemon haze seeds"

Com o link e nome das variedades de sementes em mãos, já temos duas colunas do nosso dataset. Agora vamos para o mais importante, a coleta dos nomes dos canabinoides e também dos valores percentuais de cada um deles.

Para isso, novamente foi necessário realizar uma inspeção de elementos na página, para obter os nomes de cada canabinoide da variedade.






Com a informação do elemento html, os seguintes códigos foram executados para obtenção dos nomes dos canabinoides e também dos valores de cada um deles.

html <- urls |>
    purrr::map(read_html)

  nome <- html |>
    purrr::map(xml_find_all, "//*[@class='pie_progress__label']") |>
    purrr::map(xml_text) |>
  #substitui retornos character(0) por THC. Foi necessario pois existem duas sementes que possuem uma estrutura diferente de apresentação dos valores dos canabinoides.
    lapply(\(x) if (identical(x, character(0)))
      "THC"
      else
        x)
nome
## [[1]]
## [1] "THC" "CBD" "CBG"
## 
## [[2]]
## [1] "THC" "CBD" "CBG" "CBN"
## 
## [[3]]
## [1] "THC" "CBD" "CBG" "CBN"
## 
## [[4]]
## [1] "THC" "CBD" "CBG"
## 
## [[5]]
## [1] "THC" "CBD" "CBG"
## 
## [[6]]
## [1] "THC" "CBD" "CBG" "CBN"
## 
## [[7]]
## [1] "THC" "CBD" "CBG"
## 
## [[8]]
## [1] "THC" "CBD" "CBG"
## 
## [[9]]
## [1] "THC" "CBD" "CBG"
## 
## [[10]]
## [1] "THC" "CBD" "CBG" "CBN"
## 
## [[11]]
## [1] "THC" "CBD" "CBG"
## 
## [[12]]
## [1] "THC" "CBD" "CBG"

E para os valores.

  valor <- html |>
    purrr::map(xml2::xml_find_all, "//*[@class='pie_progress']") |>
    purrr::map(xml2::xml_attr, "data-goal") |>
    purrr::map(as.numeric) |>
    lapply(\(x) if (identical(x, numeric(0)))
      0
      else
        x)
valor
## [[1]]
## [1] 22.56  0.08  0.61
## 
## [[2]]
## [1] 27.74  0.14  0.26  0.07
## 
## [[3]]
## [1] 22.58  0.19  0.22  0.02
## 
## [[4]]
## [1] 23.56  0.18  0.64
## 
## [[5]]
## [1] 24.25  0.13  1.00
## 
## [[6]]
## [1] 25.50  0.02  1.59  0.01
## 
## [[7]]
## [1] 20.92  0.19  0.25
## 
## [[8]]
## [1] 21.96  0.03  0.37
## 
## [[9]]
## [1] 18.77  0.07  0.29
## 
## [[10]]
## [1] 18.39  2.69  0.85  0.13
## 
## [[11]]
## [1] 26.55  0.04  2.27
## 
## [[12]]
## [1] 21.71  0.29  0.66

E por fim, uma função para organizar os nomes dos canabinoides com os seus respectivos valores.

dados_valores <-
    purrr::map2(nome, valor, \(x, y) tibble::tibble(name = x, value = y)) |>
    purrr::map_dfr(tidyr::pivot_wider) |>
    # substitui NAs por zero
    dplyr::mutate(dplyr::across(.fns = tidyr::replace_na, replace = 0))

dados_valores
## # A tibble: 12 x 4
##      THC   CBD   CBG   CBN
##    <dbl> <dbl> <dbl> <dbl>
##  1  22.6  0.08  0.61  0   
##  2  27.7  0.14  0.26  0.07
##  3  22.6  0.19  0.22  0.02
##  4  23.6  0.18  0.64  0   
##  5  24.2  0.13  1     0   
##  6  25.5  0.02  1.59  0.01
##  7  20.9  0.19  0.25  0   
##  8  22.0  0.03  0.37  0   
##  9  18.8  0.07  0.29  0   
## 10  18.4  2.69  0.85  0.13
## 11  26.6  0.04  2.27  0   
## 12  21.7  0.29  0.66  0

A última etapa do processo, foi a etapa de união das colunas de valores com as colunas de nomes e links.

  saida <- tibble::tibble(semente = txt, link = urls) |>
    dplyr::bind_cols(dados_valores) |>
    dplyr::mutate(link = stringr::str_squish(link))
saida
## # A tibble: 12 x 6
##    semente                      link                       THC   CBD   CBG   CBN
##    <chr>                        <chr>                    <dbl> <dbl> <dbl> <dbl>
##  1 chocolope seeds              https://www.seedbank.co~  22.6  0.08  0.61  0   
##  2 gorilla glue 4 seeds         https://www.seedbank.co~  27.7  0.14  0.26  0.07
##  3 feminized blue dream seeds   https://www.seedbank.co~  22.6  0.19  0.22  0.02
##  4 bruce banner seeds           https://www.seedbank.co~  23.6  0.18  0.64  0   
##  5 gsc seeds girl scout cookies https://www.seedbank.co~  24.2  0.13  1     0   
##  6 wedding cake seeds           https://www.seedbank.co~  25.5  0.02  1.59  0.01
##  7 northern lights 5 seeds      https://www.seedbank.co~  20.9  0.19  0.25  0   
##  8 granddaddy purple seeds      https://www.seedbank.co~  22.0  0.03  0.37  0   
##  9 auto purple kush seeds       https://www.seedbank.co~  18.8  0.07  0.29  0   
## 10 critical mass seeds          https://www.seedbank.co~  18.4  2.69  0.85  0.13
## 11 do si dos seeds              https://www.seedbank.co~  26.6  0.04  2.27  0   
## 12 auto super lemon haze seeds  https://www.seedbank.co~  21.7  0.29  0.66  0

Como foi realizada a iteração?

Para realizar a iteração, foi necessário entender primeiro, quantas páginas seriam acessadas e também quantos links seriam obtidos em cada página.

Esses valores podem ser encontrados na parte superior da página mãe.

Para coletar essa informação, foi necessário inspecionar o elemento e obter o xpath.

Em seguida, o seguinte código foi executado para obter o número de páginas e a quantidade total de itens.

n_resultados <- r_links |>
  httr::content() |>
  xml2::xml_find_first("//p[@class = 'woocommerce-result-count hide-for-medium']") |>
  xml2::xml_text() |>
  stringr::str_squish() |>
  stringr::str_extract("[0-9][0-9][0-9]") |>
  as.numeric()

n_pags <- n_resultados %/% 12 + 1

n_resultados
## [1] 118
n_pags
## [1] 10

Com isso para iterar, foi criado um vetor para coletar todas as páginas.

vetor_paginas <- 1:n_pags

E todas os trechos de código necessários para raspar os dados e coletar as informações, foram encapsulados em uma função.

baixar_pagina <- function(pag, prog = NULL) {
  Sys.sleep(1)
  
  if (!is.null(prog))
    prog()
  u_pag <-
    glue::glue("https://www.seedbank.com/collections/feminized-seeds/page/{pag}/")
  httr::GET(u_pag, httr::write_disk(
    glue::glue("output/strains/pagina_{pag}.html"),
    overwrite = TRUE
  ))
  
  links <- u_pag |>
    xml2::read_html() |>
    xml2::xml_find_all("//div[@class = 'add-to-cart-button']/a")
  
  urls <- xml2::xml_attr(links, "href")
  
  html <- urls |>
    map(read_html)
  
  nome <- html |>
    map(xml_find_all, "//*[@class='pie_progress__label']") |>
    map(xml_text) |>
    lapply(\(x) if (identical(x, character(0)))
      "THC"
      else
        x)
  
  
  valor <- html |>
    map(xml2::xml_find_all, "//*[@class='pie_progress']") |>
    map(xml2::xml_attr, "data-goal") |>
    map(as.numeric) |>
    lapply(\(x) if (identical(x, numeric(0)))
      0
      else
        x)
  
  dados_valores <-
    map2(nome, valor, \(x, y) tibble::tibble(name = x, value = y)) |>
    map_dfr(tidyr::pivot_wider) |>
    # substitui NAs por zero
    dplyr::mutate(dplyr::across(.fns = tidyr::replace_na, replace = 0))
  
  txt <-
    xml2::url_relative(urls, "https://www.seedbank.com/products/") |>
    stringr::str_replace_all("[[/-]]", " ") |>
    trimws()
  
  saida <- tibble::tibble(semente = txt, link = urls) |>
    dplyr::bind_cols(dados_valores) |>
    dplyr::mutate(link = stringr::str_squish(link))
  
  return(saida)
}

Por último, essa função recebeu o vetor já criado e iterou por todas as páginas de interesse.

progressr::with_progress({
  p <- progressr::progressor(n_pags)
  tab <- purrr::map_dfr(vetor_paginas, baixar_pagina, prog = p)
  Sys.sleep(1)
})

Como é o arquivo parseado?

Os primeiros 50 resultados do arquivo parseado, pode ser visto na tabela abaixo. Essa tabela é o dataset final da raspagem de dados e insumo inicial para elaboração da analise de clusters.

## # A tibble: 118 x 6
##    semente                          link                   THC   CBD   CBG   CBN
##    <chr>                            <chr>                <dbl> <dbl> <dbl> <dbl>
##  1 chocolope seeds                  https://www.seedban~ 22.6   0.08  0.61  0   
##  2 gorilla glue 4 seeds             https://www.seedban~ 27.7   0.14  0.26  0.07
##  3 feminized blue dream seeds       https://www.seedban~ 22.6   0.19  0.22  0.02
##  4 bruce banner seeds               https://www.seedban~ 23.6   0.18  0.64  0   
##  5 gsc seeds girl scout cookies     https://www.seedban~ 24.2   0.13  1     0   
##  6 wedding cake seeds               https://www.seedban~ 25.5   0.02  1.59  0.01
##  7 northern lights 5 seeds          https://www.seedban~ 20.9   0.19  0.25  0   
##  8 granddaddy purple seeds          https://www.seedban~ 22.0   0.03  0.37  0   
##  9 auto purple kush seeds           https://www.seedban~ 18.8   0.07  0.29  0   
## 10 critical mass seeds              https://www.seedban~ 18.4   2.69  0.85  0.13
## 11 do si dos seeds                  https://www.seedban~ 26.6   0.04  2.27  0   
## 12 auto super lemon haze seeds      https://www.seedban~ 21.7   0.29  0.66  0   
## 13 feminized platinum cookies seeds https://www.seedban~ 24.3   0.14  0.92  0.01
## 14 jack herer seeds strain          https://www.seedban~ 20.9   0.19  1.05  0   
## 15 pineapple auto seeds             https://www.seedban~ 20.7   0.06  0.27  0   
## 16 purple punch seeds               https://www.seedban~ 23.3   0.05  0.17  0   
## 17 strawberry cough seeds           https://www.seedban~ 19.5   0.22  0.04  0   
## 18 purple haze strain               https://www.seedban~ 19.7   0.11  0.76  0   
## 19 green crack seeds                https://www.seedban~ 22.5   0.16  0.65  0.01
## 20 blueberry strain seeds           https://www.seedban~ 20.0   0.13  0.14  0   
## 21 chemdawg seeds                   https://www.seedban~ 25.4   0.16  1.39  0.05
## 22 strawberry banana seeds          https://www.seedban~ 19.7   0.14  0.33  0.01
## 23 grape ape seeds                  https://www.seedban~ 22.3   0.11  0.11  0.08
## 24 zkittlez seeds                   https://www.seedban~ 21.2   0.03  0.49  0   
## 25 white widow seeds                https://www.seedban~ 25.1   0.28  0.21  0.16
## 26 skywalker og strain              https://www.seedban~ 23.9   0.15  1.17  0.12
## 27 kosher kush seeds                https://www.seedban~ 26.6   0.11  0.3   0   
## 28 bubba kush seeds                 https://www.seedban~ 23.8   0.08  0.27  0   
## 29 hilo cbd seeds 20 cbd 1 thc      https://www.seedban~  0.91 24.8   0.3   0   
## 30 cherry pie seeds                 https://www.seedban~ 16.7   0.09  0.53  0.04
## 31 northern lights 5 fast           https://www.seedban~ 17.8   0.06  1.28  0   
## 32 feminized afghan kush seeds      https://www.seedban~ 21.1   0.39  1.75  0   
## 33 alien technology seeds           https://www.seedban~ 22.4   0.02  0.34  0.1 
## 34 purple gelato seeds              https://www.seedban~ 23.5   0.02  0.82  0.01
## 35 true og kush seeds               https://www.seedban~ 26.4   0.27  0.78  0   
## 36 blue headband seeds              https://www.seedban~ 22.1   0.17  0.49  0   
## 37 5 alive seeds                    https://www.seedban~ 26.0   0.02  0.28  0.01
## 38 white rhino seeds                https://www.seedban~ 26.5   0.13  0.48  0   
## 39 trainwreck seeds                 https://www.seedban~ 25.4   0.22  0.41  0   
## 40 og kush seeds                    https://www.seedban~ 24.7   0.21  0.77  0   
## 41 alaskan thunder fuck seeds       https://www.seedban~  0     0     0     0   
## 42 runtz seeds                      https://www.seedban~ 23.0   0.02  0.64  0.01
## 43 amnesia haze cannabis seeds      https://www.seedban~ 24.5   0.25  0.21  0.13
## 44 sunset sherbet seeds             https://www.seedban~ 19.4   0.13  0.78  0   
## 45 super skunk seeds                https://www.seedban~ 20.4   0.04  0.79  0   
## 46 original skunk 1 seeds           https://www.seedban~ 19.1   0.08  0.24  0   
## 47 hindu kush seeds                 https://www.seedban~ 20.4   0.07  0.46  0   
## 48 nyc diesel seeds                 https://www.seedban~ 23.3   0.04  0.91  0   
## 49 gelato seeds                     https://www.seedban~ 22     0.04  0.59  0   
## 50 la confidential seeds            https://www.seedban~ 21.4   0.15  0.45  0.16
## # ... with 68 more rows

Documentação final






semente: nome do produto ou variedade de semente vendida no site
link: url para página de produto da semente
THC: Percentual do canabinoide THC presente na variedade
CBD: Percentual do canabinoide CBD presente na variedade
CBG: Percentual do canabinoide CBG presente na variedade
CBN: Percentual do canabinoide CBG presente na variedade

Parte 2 - Análise de cluster de canabinoides

A partir daqui, com os dados obtidos através do Web Scraping, vamos tentar identificar as variedades de sementes mais similares por quantidade percentual de canabinoides.

Essa parte do material, será a entrega para o VIII Curso de Cannabis Medicinal oferecido pela UNIFESP

Esse Curso de Cannabis Medicinal está na oitava edição e é o mais popular no Brasil. Uma referência para estudantes, acadêmicos, familiares de pacientes e quem trabalha ou quer trabalhar com quem busca acesso a produtos de saúde à base de Cannabis. O que começou nos salões da igreja do Padre Ticão, através de uma parceria entre a Unifesp, na presença do Cebrid e do Dr. Elisaldo Carlini, e de vários ativistas e coletivos. Desde a terceira edição o curso passou a ser online e já orientou milhares de inscritos.

De acordo com a programação, os principais objetivos do curso são: difundir conhecimento sobre a planta Cannabis, apresentar os possíveis medicamentos e tratamentos e seus derivados, trazem reflexões sobre a liberação da Cannabis para uso terapêutico e tratam sobre regulamentação em curso, com olhar para as esferas legislativas. Serão discutidas, ainda, formas de ampliar o acesso de pacientes aos tratamentos, de forma democrática e sustentável.

Fundamentos da política nacional sobre drogas

O que fundamenta a Política Nacional sobre drogas é a Lei Federal 11.343/2006, que em seu § 1º do art. 3º, dispõe sobre a criação do Sistema Nacional de Políticas Públicas sobre Drogas - SISNAD, entendido como “o conjunto ordenado de princípios, regras, critérios e recursos materiais e humanos que envolvem as políticas, planos, programas, ações e projetos sobre drogas, incluindo-se nele, por adesão, os Sistemas de Políticas Públics sobre Drogas dos Estados, Distrito Federal e Nunicípios” que tem a finalidade de articular, organizar e coordenar as atividades relacionadas com a prevenção do uso indevido, a atenção e a reinserção social dde usuários e dependentes de drogas e a repressão da produção não autorizada e do tráfico ilícito de drogas (art. 3º, caput, incisos I e II, da Lei de Drogas)

Fundamentação da análise

O principal objetivo de uma análise de agrupameno é o ordenamento e alocação das observações em grupos homogêneos internamente e heterogêneos entre si. A análise de agrupamentos é composta por um conjunto de técnicas exploratórias e que podem ser utilizadas quando a intenção é verificar se existem comportamentos semelhantes entre as observações (no nosso caso, cada semente de variedade é uma observação).

Entendendo essas semelhanças, intenta-se criar grupos nos quais as sementes presentes em cada grupo, serão similares do ponto de vista da quantidade de canabinoides e da variação conjunta de cada um deles. Sendo assim, vamos começar entendendo um pouco melhor cada um dos canabinoides presentes na amostra.

THC

O THC é encontrado em todas as partes da planta, mas especialmente nas flores e resina das plantas fêmeas. Já a sua concentração em cada planta depende de vários fatores, tais como o tipo de solo, o clima, a época de colheita e assim por diante.

O THC foi isolado pela primeira vez em 1964 por Raphael Mechoulam, Yechiel Gaoni e Habib Edery, ao extraí-lo a partir do haxixe com éter de petróleo, seguido de repetidas cromatografias.

A maconha possui outros alucinógenos, mas o THC é o mais potente. Os efeitos da maconha devem-se praticamente a esse composto, pois o THC modifica a atividade cerebral da pessoa, fazendo com que ela tenha alucinações, delírios, diminua a sua percepção de tempo e espaço, além de poder levar a pessoa a ter acessos de ira e pânico. fonte




CBD

“O canabidiol é uma substância encontrada na maconha, mas que não possui toxicidade se isolada. É legalizado em mais de 40 países e pesquisas têm mostrado sua eficácia em tratamentos de dores crônicas, espasmos musculares, convulsões e ansiedade.

No Brasil, o Canabidiol está registrado como medicamento na Anvisa, o que possibilita sua importação e, mais recentemente, sua fabricação em território nacional.

Apesar de ainda ser um tabu, a discussão sobre o uso da Cannabis medicinal está cada vez mais difundida e esperamos, por meio deste texto, esclarecer as principais dúvidas sobre o canabidiol.” fonte




CBG

“Os efeitos farmacológicos do CBG descritos na literatura científica incluem: atividade antifúngica, anti-inseto e anti-inflamatória; atividade neuro-protetora; estimulação do apetite e aprimoramento do processo de morte das células cancerígenas “, explica Dr. Itzhak Kurek, CEO e co-fundador da Cannformatics, uma empresa de biotecnologia do norte da Califórnia que usa uma combinação de biologia (ciência da computação e matemática, entre outras disciplinas científicas) para melhorar a cannabis medicinal.”fonte




CBN

“O CBN é um composto presente na cannabis que é criado quando o THC é deteriorado. Por este motivo, geralmente está presente em grandes quantidades quando a planta cannabis está mais velha. Embora a pesquisa atual sobre o CBN seja limitada, aos poucos os estudos realizados demonstram seus efeitos benéficos à saúde humana.” fonte




Tratamento dos dados para clusterização

O primeiro passo, foi gerar uma base selecionando as variáveis e filtrando as sementes que não tinham a mesma estrutura de coleta dos dados. Para isso, o seguinte código foi executado.

set.seed(123) 
base <- as.data.frame(tab)
base_filtrada <- dplyr::filter(base,
                               semente != "alaskan thunder fuck seeds" &
                                 semente != "sweet island skunk seeds")



feminized_seeds <- dplyr::select(base_filtrada, everything(), -link)

E com isso temos a seguinte base.

glimpse(feminized_seeds)
## Rows: 116
## Columns: 5
## $ semente <chr> "chocolope seeds", "gorilla glue 4 seeds", "feminized blue dre~
## $ THC     <dbl> 22.56, 27.74, 22.58, 23.56, 24.25, 25.50, 20.92, 21.96, 18.77,~
## $ CBD     <dbl> 0.08, 0.14, 0.19, 0.18, 0.13, 0.02, 0.19, 0.03, 0.07, 2.69, 0.~
## $ CBG     <dbl> 0.61, 0.26, 0.22, 0.64, 1.00, 1.59, 0.25, 0.37, 0.29, 0.85, 2.~
## $ CBN     <dbl> 0.00, 0.07, 0.02, 0.00, 0.00, 0.01, 0.00, 0.00, 0.00, 0.13, 0.~

Em seguida, as colunas receberam o nome de cada planta, pois o algoritmo de clusterização que será utilizado aceita apenas variáveis quantitativas que nesse caso, são os percentuais de cada canabinoide. Além disso, a base passou por um processo de padronização, conhecido como z-scores, para saber mais sobre esse procedimento, leia aqui

rownames(feminized_seeds) <- feminized_seeds[, 1]
feminized_seeds <- feminized_seeds[,-1]

feminized_seeds.padronizado <- scale(feminized_seeds)

Em seguida, o algoritmo k-means foi utilizado para gerar os primeiros 2 clusters. Para isso, o código abaixo foi executado.

#Cluster não hierarquico


feminized_seeds.k2 <-
  kmeans(feminized_seeds.padronizado, centers = 2)

#Visualizar os clusters

fviz_cluster(feminized_seeds.k2, data = feminized_seeds.padronizado, main = "Cluster k2")

Através do gráfico gerado, é possível perceber que existe uma quebra inicial interessante, quando consideramos o comportamento conjunto das variáveis para criar os grupos.

Quando utilizamos essa técnica de clusterização não hierarquica, é necessário indicar apriori o número de clusters que será utilizado. Para isso, foram geradas algumas visualizações de diferentes conjuntos de clusters.

#Criando Clusters

feminized_seeds.k3 <-
  kmeans(feminized_seeds.padronizado, centers = 3)
feminized_seeds.k4 <-
  kmeans(feminized_seeds.padronizado, centers = 4)
feminized_seeds.k5 <-
  kmeans(feminized_seeds.padronizado, centers = 5)
feminized_seeds.k6 <-
  kmeans(feminized_seeds.padronizado, centers = 6)

tipo_geom <- "points"
#Criar graficos
G2 <-
  fviz_cluster(feminized_seeds.k2, geom = tipo_geom, data = feminized_seeds.padronizado) + ggtitle("k = 2")
G3 <-
  fviz_cluster(feminized_seeds.k3, geom = tipo_geom, data = feminized_seeds.padronizado) + ggtitle("k = 3")
G4 <-
  fviz_cluster(feminized_seeds.k4, geom = tipo_geom, data = feminized_seeds.padronizado) + ggtitle("k = 4")
G5 <-
  fviz_cluster(feminized_seeds.k5, geom = tipo_geom, data = feminized_seeds.padronizado) + ggtitle("k = 5")
G6 <-
  fviz_cluster(feminized_seeds.k6, geom = tipo_geom, data = feminized_seeds.padronizado) + ggtitle("k = 6")


#Imprimir graficos na mesma tela
grid.arrange(G2, G3, G4, G5, G6, nrow = 2)

O método Elbow foi utilizado para determinação do número ótimo de clusters. Para saber mais sobre o método Elbow, leia aqui

#VERIFICANDO ELBOW
fviz_nbclust(feminized_seeds.padronizado, kmeans, method = "wss") +
  geom_vline(xintercept = 5, linetype = 6)

Foi tomada a decisão de trabalhar com 5 clusters de sementes e uma forma de avaliar as características desses clusters é gerando um dataset de resumo, agrupando as observações e calculando as médias de cada grupo.

fit <- data.frame(feminized_seeds.k5$cluster)

feminized_seeds_fit <- cbind(base_filtrada, fit)

resumo_medio <- feminized_seeds_fit |>
  group_by(feminized_seeds.k5.cluster) |>
  dplyr::summarise(
    n = n(),
    THC = mean(THC),
    CBD = mean(CBD),
    CBG = mean(CBG),
    CBN = mean(CBN)
  ) 

print(resumo_medio)
## # A tibble: 5 x 6
##   feminized_seeds.k5.cluster     n   THC    CBD   CBG    CBN
##                        <int> <int> <dbl>  <dbl> <dbl>  <dbl>
## 1                          1    73 21.3   0.109 0.443 0.0105
## 2                          2    23 22.8   0.106 1.17  0.0187
## 3                          3    13 20.1   3.64  0.542 0.184 
## 4                          4     1  9.23  8.1   5.39  0.2   
## 5                          5     6  5.83 14.7   0.553 0.0283

Com os clusters formados, é possível ter uma ideia do percentual médio de cada canabinoide em cada cluster.

O cluster 4 por exemplo, possui apenas 1 variedade de semente e isso ocorreu pois é possível que essa semente específica tenha no comportamento conjunto de suas variáveis métricas, valores que são consideravelmente diferentes para a quantidade de clusters que fora considerada nessa análise.

Com esses resultados e pensando na realização de cultivo e a grande variedade de sementes presentes no banco, é possível avaliar cada variedade em cada grupo, já com uma ideia média do percentual de cada canabinoide coletado em cada semente.

Para acessar os dados desse relatório, acesse o diretório desse projeto no Github. Lá na pasta outputs, existe um arquivo .csv com os resultado dos clusters e de quais sementes fazem parte deles.

Espero que tenha ficado legal para você que lê. Foi muito divertido fazer esse trabalho :-)
Todo feedback é bem vindo!




Até mais!!

Eduardo Ben- Hur - Linkedin